﻿#region HeaderComments
// ***********************************************************************************************************************************************
// Copyright (C) # YEAR # # York #
// 作    者：# CaiTao #
// 创建日期：# CREATIONDATE #
// 功能描述：# Json读写 #
// 修改记录：# MODIFICATIONRECORD #
// ***********************************************************************************************************************************************
#endregion
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;

namespace York.JSONConfig
{
    public class JsonRW
    {
        #region Json Read Write
        /// <summary>
        /// 写入json到文件
        /// </summary>
        /// <param name="FileName"></param>
        /// <param name="jsonString"></param>
        public static void WriteJsonToFile(string FileName, string jsonString)
        {
            StreamWriter writer;

            FileInfo file = new FileInfo(FileName);
            if (!file.Exists)
            {
                writer = file.CreateText();
            }
            else   //覆盖式写入
            {
                file.Delete();
                writer = file.CreateText();
            }
            writer.Write(jsonString);
            writer.Flush();
            writer.Dispose();
            writer.Close();
        }

        /// <summary>
        /// 从文件中读取json
        /// </summary>
        /// <param name="FileName"></param>
        public static string ReadJsonFromFile(string FileName)
        {
            StreamReader reader;

            FileInfo file = new FileInfo(FileName);

            reader = file.OpenText();

            string data = reader.ReadToEnd();

            reader.Dispose();
            reader.Close();

            return data;
        }

        /// <summary>
        /// 从文件中读取json
        /// </summary>
        /// <param name="FileName"></param>
        public static JObject ReadJsonFromFile_ToJobject(string FileName)
        {
            StreamReader reader;

            FileInfo file = new FileInfo(FileName);

            reader = file.OpenText();

            string data = reader.ReadToEnd();

            reader.Dispose();
            reader.Close();

            return DeSerializer<JObject>(data);
        }
        #endregion

        #region Create Property
        /// <summary>
        /// 创建一个任意内容的属性
        /// </summary>
        /// <param name="propertyName"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        public static JProperty CreateProperty(string propertyName, object content)
        {
            JProperty property = new JProperty(propertyName, content);
            return property;
        }

        /// <summary>
        /// 创建一个数组类型的属性
        /// </summary>
        /// <param name="propertyName"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        public static JProperty CreateProperty(string propertyName, object[] content)
        {
            JProperty property = new JProperty(propertyName, CreateArray(content));
            return property;
        }
        #endregion

        #region Create Array
        /// <summary>
        /// 创建一个包含任意内容的json数组
        /// </summary>
        /// <param name="content"></param>
        /// <returns></returns>
        public static JArray CreateArray(object[] content)
        {
            JArray array = new JArray(
               content.Select(x => new JValue(x))
            );
            return array;
        }

        public static JArray CreateArray(List<Guid> content)
        {
            JArray array = new JArray(
               content.Select(x => new JValue(x.ToString()))
            );
            return array;
        }

        /// <summary>
        /// 创建一个包含jobject对象的数组
        /// </summary>
        /// <param name="content"></param>
        /// <returns></returns>
        public static JArray CreateArray(JObject[] content)
        {
            JArray array = new JArray(content);
            return array;
        }


        /// <summary>
        /// 创建一个空json数组
        /// </summary>
        /// <returns></returns>
        public static JArray CreateArray()
        {
            JArray array = new JArray();
            return array;
        }
        #endregion

        #region Create JObject
        /// <summary>
        /// 创建多属性json对象
        /// </summary>
        /// <param name="jProperties"></param>
        /// <returns></returns>
        public static JObject CreateObject(params JProperty[] jProperties)
        {
            JObject jObject = new JObject(jProperties);
            return jObject;
        }

        /// <summary>
        /// 创建一个空json对象
        /// </summary>
        /// <returns></returns>
        public static JObject CreateObject()
        {
            JObject jObject = new JObject();
            return jObject;
        }

        /// <summary>
        /// 创建Json对象并添加一个属性
        /// </summary>
        /// <param name="jPropertie"></param>
        /// <returns></returns>
        public static JObject CreateObject(JProperty jPropertie)
        {
            JObject jObject = new JObject(jPropertie);
            return jObject;
        }

        #endregion

        #region Serializer
        /// <summary>
        /// 反序列化对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="deSerializer"></param>
        /// <returns></returns>
        public static T DeSerializer<T>(string json)
        {
            T jobj = JsonConvert.DeserializeObject<T>(json);
            return jobj;
        }

        /// <summary>
        /// 序列化对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="serializerObj"></param>
        /// <returns></returns>
        public static string Serializer<T>(T json, bool indented = true)
        {
            if (indented)
            {
                return JsonConvert.SerializeObject(json, Formatting.Indented);
            }
            else
            {
                return JsonConvert.SerializeObject(json);
            }
        }

        #endregion

        #region Jobject 和类的转换

        /// <summary>
        ///  JObject 转换成其他类
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="json"></param>
        /// <returns></returns>
        public static T JObjectTo<T>(JObject json)
        {
            string jsonStr = Serializer<JObject>(json);
            T to = DeSerializer<T>(jsonStr);
            return to;
        }

        public static T JTokenTo<T>(JToken json)
        {
            string jsonStr = Serializer<JToken>(json);
            T to = DeSerializer<T>(jsonStr);
            return to;
        }

        /// <summary>
        /// 其他类转换成Jobject
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="json"></param>
        /// <returns></returns>
        public static JObject ToJObject<T>(T json)
        {
            string jsonStr = Serializer<T>(json);
            JObject to = DeSerializer<JObject>(jsonStr);
            return to;
        }
        #endregion

        #region 通用方法

        /// <summary>
        /// 读取对象
        /// </summary>
        /// <param name="configName"></param>
        /// <param name="configItem"></param>
        public static T GetJToken<T>(JToken parentJToken, string propertyName) where T : JToken
        {          
            return parentJToken?.Value<T>(propertyName);
        }

        /// <summary>
        /// 将Jobject写入到配置文件中
        /// </summary>
        /// <param name="configName"></param>
        /// <param name="jObject"></param>
        public static void WriteJsonToFile_JObj(string configName, JObject jObject)
        {
            string jsonStr = Serializer(jObject);

            string configPath = ConfigSetting.Instance.GetConfigFile(configName);
            if (string.IsNullOrEmpty(configPath))
            {
                configPath = ConfigSetting.Instance.CreateConfigFile(configName);
            }
            WriteJsonToFile(configPath, jsonStr);
        }

        /// <summary>
        /// 将泛型写入到配置文件中
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="configName"></param>
        /// <param name="TJson"></param>
        public static void WriteJsonToFile_T<T>(string configName, T TJson)
        {
            string jsonStr = Serializer(TJson);

            string configPath = ConfigSetting.Instance.GetConfigFile(configName);

            if (string.IsNullOrEmpty(configPath))
            {
                configPath = ConfigSetting.Instance.CreateConfigFile(configName);
            }

            WriteJsonToFile(configPath, jsonStr);
        }

        public static void WriteJsonToFile_T<T>(string dir,string configName, T TJson)
        {
            string jsonStr = Serializer(TJson);

            string configPath = ConfigSetting.Instance.GetConfigFile(dir,configName);

            if (string.IsNullOrEmpty(configPath))
            {
                configPath = ConfigSetting.Instance.CreateConfigFile(dir,configName);
            }

            WriteJsonToFile(configPath, jsonStr);
        }

        /// <summary>
        /// 将JArray写入到配置文件中
        /// </summary>
        /// <param name="configName"></param>
        /// <param name="jObject"></param>
        public static void WriteJsonToFile_JArray(string configName, JArray jArray)
        {
            string jsonStr = Serializer(jArray);

            string configPath = ConfigSetting.Instance.GetConfigFile(configName);
            if (string.IsNullOrEmpty(configPath))
            {
                configPath = ConfigSetting.Instance.CreateConfigFile(configName);
            }
            WriteJsonToFile(configPath, jsonStr);
        }

        /// <summary>
        /// 将jsonStr写入到配置文件中
        /// </summary>
        /// <param name="configName"></param>
        /// <param name="jObject"></param>
        public static void WriteJsonToFile_JStr(string configName, string jsonStr)
        {
            string configPath = ConfigSetting.Instance.GetConfigFile(configName);
            if (string.IsNullOrEmpty(configPath))
            {
                configPath = ConfigSetting.Instance.CreateConfigFile(configName);
            }
            WriteJsonToFile(configPath, jsonStr);
        }

       
        #region 一级读取
        /// <summary>
        /// 读取整个配置文件对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="configName"></param>
        /// <returns></returns>
        public static T GetConfigJson<T>(string configName) where T : JToken
        {
            return (T)ConfigSetting.Instance[configName];
        }

        #endregion

        #region 二级读取
        /// <summary>
        /// 读取二级对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="configName"></param>
        /// <param name="configItem"></param>
        /// <returns></returns>
        public static T GetJToken<T>(string configName, string configItem) where T : JToken
        {
            JToken level1 = ConfigSetting.Instance[configName];
           
            T level2 = GetJToken<T>(level1, configItem);

            return level2;
        }
        #endregion

        #region 三级读取
        /// <summary>
        /// 读取三级对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="configName"></param>
        /// <param name="configItem1"></param>
        /// <param name="configItem2"></param>
        /// <returns></returns>
        public static T GetJToken<T>(string configName, string configItem1, string configItem2) where T : JToken
        {
            JToken level1 = ConfigSetting.Instance[configName];
            JToken level2 = GetJToken<JToken>(level1, configItem1);
            T level3 = GetJToken<T>(level2, configItem2);
            return level3;
        }
        #endregion
        #endregion
    }
}

